package com.cmas.platform.service.impl;

import com.aidex.common.annotation.DataSource;
import com.aidex.common.enums.DataSourceType;
import com.aidex.common.utils.ObjectUtils;
import com.aidex.common.utils.SecurityUtils;
import com.aidex.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmas.platform.domain.*;
import com.cmas.platform.domain.em.ApproveStatusEnum;
import com.cmas.platform.dto.PostDto;
import com.cmas.platform.mapper.PostFullMapper;
import com.cmas.platform.service.*;
import com.cmas.platform.utils.ConvertUtil;
import com.cmas.platform.utils.DataRedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author su
 * @Date 2023/5/2 0:12
 */
@Service
public class PostFullDtoServiceImpl extends ServiceImpl<PostFullMapper, PostDto> implements PostFullService {
    private static final Logger log = LoggerFactory.getLogger(PostFullDtoServiceImpl.class);

    @Autowired
    private PostService postService;
    @Autowired
    private RegionService regionService;
    @Autowired
    private SectionService sectionService;
    @Autowired
    private UserLikeService userLikeService;
    @Autowired
    private DataRedisUtil dataRedisUtil;

    @Autowired
    private UserRecordService userRecordService;


    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public IPage<PostDto> selectPostFullDto(Integer current, Integer size, Post post) {
        Page<PostDto> page = new Page<>(current, size);
        page.setRecords(baseMapper.selectPostDtoList(setCurrent(current, size), size, setQueryWrapper(post)));
        return page;
    }

    @Override
    public List<PostDto> selectPostFullDto(List<String> ids) {
        return baseMapper.selectPostByIdsDtoList(ids);
    }


    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public IPage<PostDto> selectKeyWordPostFullDto(Integer current, Integer size, Post post) {
        Page<PostDto> page = new Page<>(current, size);
        QueryWrapper<Post> postQueryWrapper = setQueryWrapper(post);
        if (StringUtils.isNotEmpty(post.getContent())) {
            postQueryWrapper.lambda().or().like(Post::getTitle, post.getContent())
                    .in(Post::getStatus, ApproveStatusEnum.AUTOMATIC_PASS.getValue(),
                            ApproveStatusEnum.ARTIFICIAL_PASS.getValue());
            if(StringUtils.isNotEmpty(post.getRegionId())){
                postQueryWrapper.lambda().eq(Post::getRegionId,post.getRegionId());
            }
        }
        page.setRecords(baseMapper.selectPostDtoList(setCurrent(current, size), size, postQueryWrapper));
        return page;
    }


    /**
     * 更新redis数据
     *
     * @param post
     */
    @DataSource(value = DataSourceType.SLAVE)
    @Override
    public void reloadPost(Post post) {
        if (post.getStatus().equals(ApproveStatusEnum.AUTOMATIC_PASS.getValue())
                || post.getStatus().equals(ApproveStatusEnum.ARTIFICIAL_PASS.getValue())) {
            Region region = regionService.getById(post.getRegionId());
            Section section = sectionService.getById(post.getSectionId());
            dataRedisUtil.addRedisPost(region.getCode(), section.getCode(), post.getId());
        }
    }


    @Override
    public IPage<PostDto> getPostFullDto(Integer pageNo, Integer pageSize, Post post) {
        Page<PostDto> page = new Page<>(pageNo, pageSize);
        List<PostDto> redisPost = new ArrayList<>();
        if (StringUtils.isNotEmpty(post.getRegionId())) {
            redisPost = indexOrOther(pageNo, pageSize, post);
        } else if (StringUtils.isEmpty(post.getRegionId()) &&
                StringUtils.isNotEmpty(post.getSectionId())) {
            Section section = sectionService.getOne(new QueryWrapper<Section>().lambda()
                    .ne(Section::getCode, "index")
                    .eq(Section::getId, post.getSectionId()));
            if (section != null) {
                redisPost = ConvertUtil.castList(dataRedisUtil.
                        getRedisSectionPost(pageNo, pageSize, null, section.getCode()), PostDto.class);
            } else {
                post.setSectionId(null);
                redisPost = ConvertUtil.castList(dataRedisUtil.getRedisRankPost(pageNo, pageSize), PostDto.class);
            }
        } else {
            redisPost = ConvertUtil.castList(dataRedisUtil.getRedisRankPost(pageNo, pageSize), PostDto.class);
        }
        if (redisPost.isEmpty()) {
            redisPost = baseMapper.selectPostDtoList(setCurrent(pageNo, pageSize),
                    setSize(pageNo, pageSize), setQueryWrapper(post));
        }

        page.setRecords(setUserRecord(redisPost));
        return page;
    }

    @Override
    public PostDto getPostDetail(String id) {
        if (StringUtils.isNotEmpty(id)) {
            PostDto postDto = baseMapper.selectPostDto(id);
            if (ObjectUtils.isNotEmpty(postDto)) {
                // 获取当前的用户ID
                String userId = SecurityUtils.getUserId();
                UserLike userLike = userLikeService
                        .getOne(new QueryWrapper<UserLike>().lambda().eq(UserLike::getUserId, userId).
                                eq(UserLike::getItemId, id));
                if (userLike != null && userLike.getIsLike().equals("1")) {
                    postDto.setIsLike(true);
                }
                return postDto;
            }
        }
        return null;
    }

    @DataSource(value = DataSourceType.SLAVE)
    public PostDto getPost(String id) {
        if (StringUtils.isNotEmpty(id)) {
            return baseMapper.selectPostDto(id);
        }
        return null;
    }


    private List<PostDto> indexOrOther(Integer pageNo, Integer pageSize, Post post) {
        Region region = regionService.getById(post.getRegionId());
        List<PostDto> redisPost = new ArrayList<>();
        if (region != null) {
            if (StringUtils.isNotEmpty(post.getSectionId())) {
                Section section = sectionService.getOne(new QueryWrapper<Section>().lambda()
                        .ne(Section::getCode, "index")
                        .eq(Section::getId, post.getSectionId()));
                if (section != null) {
                    redisPost = ConvertUtil.castList(dataRedisUtil.
                            getRedisSectionPost(pageNo, pageSize, region.getCode(), section.getCode()), PostDto.class);
                    if (redisPost.isEmpty()) {
                        dataRedisUtil.addRedisSectionPostList(region, section);
                    }
                } else {
                    redisPost = ConvertUtil.castList(dataRedisUtil
                            .getRedisRegionPost(pageNo, pageSize, region.getCode()), PostDto.class);
                }
            } else {
                redisPost = ConvertUtil.castList(dataRedisUtil
                        .getRedisRegionPost(pageNo, pageSize, region.getCode()), PostDto.class);
                if (redisPost.isEmpty()) {
                    dataRedisUtil.addRedisRegionPostList(region);
                }
            }
        }
        return redisPost;
    }


    private List<PostDto> setUserRecord(List<PostDto> postDtoList) {
        if (!postDtoList.isEmpty()) {
            // 获取当前的用户ID
            String userId = SecurityUtils.getUserId();
            List<String> postIds = postDtoList.stream().map(PostDto::getId)
                    .collect(Collectors.toList());
            List<UserLike> userLikeList = userLikeService
                    .list(new QueryWrapper<UserLike>().lambda()
                            .eq(UserLike::getUserId, userId).in(UserLike::getItemId, postIds));
            if (!userLikeList.isEmpty()) {
                for (PostDto postDto : postDtoList) {
                    postDto.setIsLike(false);
                    for (UserLike userLike : userLikeList) {
                        if (postDto.getId().equals(userLike.getItemId())
                                && userLike.getIsLike().equals("1")) {
                            postDto.setIsLike(true);
                        }
                    }
                }
            }
        }
        return postDtoList;
    }

    private QueryWrapper<Post> setQueryWrapper(Post post) {
        if (StringUtils.isEmpty(post.getStatus())) {
            post.setStatus(ApproveStatusEnum.AUTOMATIC_PASS.getValue() + ","
                    + ApproveStatusEnum.ARTIFICIAL_PASS.getValue());
        }
        return postService.setQueryWrapper(post);
    }


    private Integer setCurrent(Integer current, Integer size) {
        int start = 0;
        if (current > 1) {
            start = current * size - size;
        }
        return start;
    }

    private Integer setSize(Integer current, Integer size) {
        return current * size;
    }
}
